package com.wxw.BaseLibrary.net;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import com.google.gson.Gson;
import com.pusys.bean.Constants;
import com.pusys.bean.DataPackage;
import com.pusys.bean.MessageType;
import com.wxw.BaseLibrary.tool.AES;
import com.wxw.BaseLibrary.tool.Base64;
import com.wxw.BaseLibrary.tool.SystemTool;

import java.io.*;
import java.net.Socket;

public class TcpClient {
    private PrintWriter mPrintWriter;
    private BufferedReader mBufferedReader;
    private Socket mSocket;

    private Handler mReceiveHandler;
    private Handler mWriteHandler;

    private Gson mGson;

    private String mHost;
    private int mPort;
    private boolean running = false;

    public TcpClient(Handler receiveHandler, String host, int port) {
        this.mReceiveHandler = receiveHandler;
        this.mHost = host;
        this.mPort = port;
        mGson = new Gson();
    }

    private void doConnect() {
        try {
            mSocket = new Socket(mHost, mPort);
            mPrintWriter = new PrintWriter(mSocket.getOutputStream());
            mBufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
            running = true;
            new Thread() {
                @Override
                public void run() {
                    super.run();
                    try {
                        while(running) {
                            String content = null;
                            if ((content = mBufferedReader.readLine()) != null) {
                                content = SystemTool.unicode2String(AES.decode(content));
                                DataPackage data = mGson.fromJson(content, DataPackage.class);
                                int what = 0;
                                if (data.getDataType() == MessageType.TEXT_MESSAGE.value()) {
                                    what = Constants.TRANSFER_STR.getCode();
                                } else {
                                    what = Constants.TRANSFER_FILE.getCode();
                                }
                                showReceiveMsg(content, what);
                            }
                            try {
                                Thread.sleep(200);
                            } catch (Exception ex) {
                                ex.printStackTrace();
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();

            Looper.prepare();
            mWriteHandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    if (msg.what == Constants.SEND_MSG.getCode()) {
                        mPrintWriter.write(msg.obj.toString() + "\r\n");
                        mPrintWriter.flush();
                    } else if (msg.what == Constants.SEND_FILE.getCode()) {
                        sendFile(msg.obj.toString());
                    }
                }
            };
            Looper.loop();
        } catch (IOException e) {
            e.printStackTrace();
            //出现异常关闭资源
            close();
        }
    }

    /**
     * 文件路径
     *
     * @param filePath
     */
    private void sendFile(String filePath) {
        FileInputStream fis = null;
        File file = new File(filePath);

        try {
            mReceiveHandler.sendEmptyMessage(Constants.PROGRESS.getCode());

            fis = new FileInputStream(file);

            DataPackage dataPackage = new DataPackage();
            dataPackage.setDataType(Constants.TRANSFER_FILE.getCode());
            dataPackage.setFileName(file.getName());
            dataPackage.setFileSize(file.length());
            dataPackage.setTransLength(0);


            byte[] bytes = new byte[1024];
            int length = 0;
            while ((length = fis.read(bytes, 0, bytes.length)) != -1) {
                dataPackage.setTransLength(dataPackage.getTransLength() + length);
                dataPackage.setData(Base64.encode(bytes));
                mPrintWriter.write(mGson.toJson(dataPackage) + "\r\n");
                mPrintWriter.flush();

                showReceiveMsg(100 * dataPackage.getTransLength() / dataPackage.getFileSize(), Constants.PROGRESS.getCode());
            }
            fis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            mPrintWriter.close();
        }
    }

    private void close() {
        try {
            if (mPrintWriter != null) {
                mPrintWriter.close();
            }
            if (mBufferedReader != null) {
                mBufferedReader.close();
            }
            if (mSocket != null) {
                mSocket.close();
            }
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }

    public void start() {
        new Thread() {
            @Override
            public void run() {
                super.run();
                doConnect();
                int i = 0;
                while (i<5) {
                    try {
                        Thread.sleep(500);
                        if (isConntected()) {
                            showReceiveMsg("SocketConnected", Constants.SYSTEM_MSG.getCode());
                            i=5;
                        }
                        i++;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

    public void stop() {
        running = false;
        close();
    }

    public void showReceiveMsg(Object msg, int what) {
        if (mReceiveHandler != null) {
            Message message = new Message();
            message.what = what;
            message.obj = msg;
            mReceiveHandler.sendMessage(message);
        }

    }

    public String getHost() {
        return mHost;
    }

    public void setHost(String host) {
        this.mHost = host;
    }

    public int getPort() {
        return mPort;
    }

    public void setPort(int port) {
        this.mPort = port;
    }

    public Handler getWriteHandler() {
        return mWriteHandler;
    }

    public void setWriteHandler(Handler writeHandler) {
        mWriteHandler = writeHandler;
    }

    public Handler getReceiveHandler() {
        return mReceiveHandler;
    }

    public void setReceiveHandler(Handler sendHandler) {
        mReceiveHandler = sendHandler;
    }

    public boolean isConntected() {
        if (mSocket == null) {
            return false;
        }
        return mSocket.isConnected();
    }
}
